from editor_base import EditorBase
from categories import CategoryEditor

from ..bases import widgets

class AttributeEditor(EditorBase):
    topwidget_label = 'Attribute'
    def init_editor(self, **kwargs):
        self.attribute = kwargs.get('attribute')
        
        self.txtName = widgets.Entry(label='Name', Property=(self.attribute, 'name'))
        #self.txtName = widgets.Text(label='Name', src_object=self.attribute, 
        #                            src_attr='name', allow_obj_setattr=True)
        self.topwidget.pack_start(self.txtName.topwidget)
        
        if self.attribute.saved_class_name in ['DefinitionAttribute', 'PatchedAttribute']:
            self.sbChan = widgets.SpinBtn(label='Channel', Property=(self.attribute, 'Index'))
            self.topwidget.pack_start(self.sbChan.topwidget)
            self.cbSixteenBit = widgets.CheckBox(label='16 bit mode')
            self.cbSixteenBit.state = self.attribute.sixteen_bit
            self.cbSixteenBit.connect('clicked', self.on_cbSixteenBit_clicked)
            self.topwidget.pack_start(self.cbSixteenBit)
            #self.attribute.connect('chan_index_changed', self.sbChan.on_object_value_changed)
            self.attribute.bind(sixteen_bit=self.on_sixteen_bit_set)
        else:
            self.sbChan = None
            obj = self.make_child_editor(CategoryEditor, 'categories', src_object=self.attribute)
            self.topwidget.pack_start(obj.topwidget)
        
        self.sbInitVal = widgets.SpinBtn(label='Initial Value', Property=(self.attribute, 'initial_value'))
        self.topwidget.pack_start(self.sbInitVal.topwidget)
        
        obj = self.make_child_editor(ParameterEditor, 'parameters', attribute=self.attribute)
        self.topwidget.pack_start(obj.topwidget, expand=True)
        
        #self.attribute.connect('attr_watch_name', self.txtName.on_object_value_changed)
        
    def unlink(self):
        super(AttributeEditor, self).unlink()
        self.txtName.unlink()
        self.sbInitVal.unlink()
        self.attribute.unbind(self.on_sixteen_bit_set)
        if self.sbChan is not None:
            self.sbChan.unlink()
        
    def on_cbSixteenBit_clicked(self, cb):
        if self.attribute.sixteen_bit != cb.state:
            self.attribute.sixteen_bit = cb.state
        
    def on_sixteen_bit_set(self, **kwargs):
        value = kwargs.get('value')
        if value != self.cbSixteenBit.state:
            self.cbSixteenBit.state = value
            

class ParameterEditor(EditorBase):
    topwidget_label = 'Parameters'
    def init_editor(self, **kwargs):
        self.attribute = kwargs.get('attribute')
        
        if self.attribute.saved_class_name == 'GlobalAttribute':
            self.global_param_list = widgets.TreeList(name='Parameters', column_names=['id', 'Name'], 
                                                      column_order=[1], columns_editable=[1])
            self.global_param_list.connect('cell_edited', self.on_global_list_cell_edited)
            self.global_param_source = self.attribute
            btn = widgets.Button(label='Add Parameter')
            btn.connect('clicked', self.on_btnAddGlobalParam_clicked)
            self.global_param_list.topwidget.pack_start(btn)
            self.topwidget = self.global_param_list.topwidget
            
        elif self.attribute.saved_class_name == 'DefinitionAttribute':
            d = dict(name='Parameters', column_names=['id', 'Name', 'Range Lo', 'Range Hi'], default_sort_column=2, 
                     column_order=[1, 2, 3], columns_editable=[2, 3], list_types=[str, str, int, int])
            self.definition_param_list = widgets.TreeList(**d)
            self.definition_param_list.connect('cell_edited', self.on_definition_list_cell_edited)
            
            self.update_definition_param_list()
            self.global_param_list = widgets.Combo(name='Add Parameter', list_types=[str, str])
            self.global_param_source = self.attribute.GlobalAttribute
            
            btn = widgets.Button(label='Add')
            btn.connect('clicked', self.on_btnAddDefinitionParam_clicked)
            self.global_param_list.topwidget.pack_start(btn)
            btn = widgets.Button(label='Delete')
            btn.connect('clicked', self.on_btnDelDefinitionParam_clicked)
            self.definition_param_list.topwidget.pack_start(btn)
            
            self.definition_param_list.topwidget.pack_start(self.global_param_list.topwidget, expand=True)
            self.attribute.connect('new_indexed_parameter', self.update_definition_param_list)
            self.topwidget = self.definition_param_list.topwidget
            
        self.update_global_param_list()
        self.global_param_source.connect('new_indexed_parameter', self.update_global_param_list)
        
    def unlink(self):
        super(ParameterEditor, self).unlink()
        self.global_param_source.disconnect(callback=self.update_global_param_list)
        self.attribute.disconnect(callback=self.update_definition_param_list)
            
    def update_global_param_list(self, **kwargs):
        param = kwargs.get('parameter')
        key = kwargs.get('key')
        if key and not param:
            param = self.global_param_source.indexed_parameters.get(key)
        if param:
            self.global_param_list.update({param.id:param.name})
        else:
            for key, val in self.global_param_source.indexed_parameters.iteritems():
                self.global_param_list.update({key:val.name})
        
    def update_definition_param_list(self, **kwargs):
        param = kwargs.get('parameter')
        key = kwargs.get('key')
        if key and not param:
            param = self.attribute.indexed_parameters.get(key)
        if param:
            values = [getattr(param, attr) for attr in ['name', 'value_min', 'value_max']]
            self.definition_param_list.update({param.id:values})
        else:
            for key, val in self.attribute.indexed_parameters.iteritems():
                values = [getattr(val, attr) for attr in ['name', 'value_min', 'value_max']]
                self.definition_param_list.update({key:values})
    
    def on_btnAddGlobalParam_clicked(self, btn):
        self.attribute.add_indexed_parameter(name='New Parameter')
    
    def on_btnAddDefinitionParam_clicked(self, btn):
        gkey = self.global_param_list.current_selection
        if gkey:
            self.attribute.add_indexed_parameter(global_parameter_id=gkey)
        
    def on_btnDelDefinitionParam_clicked(self, btn):
        key = self.definition_param_list.current_selection
        if key:
            self.attribute.del_indexed_parameter(id=key)
            self.definition_param_list.clear()
            self.update_definition_param_list()
        
    def on_global_list_cell_edited(self, **kwargs):
        key = kwargs.get('key')
        column = kwargs.get('column')
        value = kwargs.get('value')
        self.global_param_source.indexed_parameters[key].name = value
        self.update_global_param_list(key=key)
        
    def on_definition_list_cell_edited(self, **kwargs):
        key = kwargs.get('key')
        column = kwargs.get('column')
        value = kwargs.get('value')
        d = {2:'value_min', 3:'value_max'}
        setattr(self.attribute.indexed_parameters[key], d[column], value)
        self.update_definition_param_list(key=key)
